package com.hospital.register.order.controller.website;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hospital.register.common.exception.BusinessException;
import com.hospital.register.common.result.Result;
import com.hospital.register.common.result.ResultCodeEnum;
import com.hospital.register.common.utils.AuthContextHolder;
import com.hospital.register.dto.order.OrderDayDto;
import com.hospital.register.dto.order.OrderPageDto;
import com.hospital.register.dto.order.OrderSubmissionDto;
import com.hospital.register.enums.OrderStatusEnum;
import com.hospital.register.enums.PaymentTypeEnum;
import com.hospital.register.model.order.RefundInfo;
import com.hospital.register.order.service.OrderInfoService;
import com.hospital.register.vo.order.OrderDaysVo;
import com.hospital.register.vo.order.OrderQueryVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

@Api(tags = "订单管理", description = "面向用户")
@RestController
@RequestMapping("/api/order/orderInfo")
@Validated
public class OrderInfoSiteController {

    /**
     * 处理订单业务
     */
    @Autowired
    private OrderInfoService orderInfoService;

    @ApiOperation("提交挂号订单")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "scheduleId", value = "排班的 id", required = true, paramType = "path", dataTypeClass = String.class),
            @ApiImplicitParam(name = "patientId", value = "就诊人的 id", required = true, paramType = "path", dataTypeClass = String.class)
    })
    @PostMapping("/auth/submitOrder/{scheduleId}/{patientId}")
    public Result<Long> submitOrder(
            @PathVariable @NotBlank(message = "排班 id 不可为空") String scheduleId,
            @PathVariable @NotNull(message = "就诊人 id 不可为空") @Min(value = 0L, message = "就诊人 id 非法") Long patientId,
            @ApiIgnore HttpServletRequest request) {
        Long userId = AuthContextHolder.getUserId(request);

        OrderSubmissionDto conditions = new OrderSubmissionDto();
        conditions.setScheduleId(scheduleId);
        conditions.setPatientId(patientId);
        conditions.setUserId(userId);

        return Result.ok(this.orderInfoService.submit(conditions));
    }

    @ApiOperation("根据 id 查询订单")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderId", value = "订单的 id", required = true, paramType = "path", dataTypeClass = String.class),
    })
    @GetMapping("/auth/getOrderInfo/{orderId}")
    public Result<OrderQueryVo> getOrders(
            @PathVariable @NotNull(message = "订单 id 不可为空") Long orderId,
            @ApiIgnore HttpServletRequest request) {
        Long userId = AuthContextHolder.getUserId(request);
        OrderQueryVo order = this.orderInfoService.selectById(orderId);
        if (!userId.equals(order.getUserId())) {
            throw new BusinessException("对应的订单不存在", ResultCodeEnum.PARAM_ERROR.getCode());
        }
        return Result.ok(order);
    }

    @ApiOperation("分页查询订单列表")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "page", value = "页码", required = true, paramType = "path", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "limit", value = "每页记录数", required = true, paramType = "path", dataTypeClass = Long.class)
    })
    @GetMapping("/auth/{page}/{limit}")
    public Result<Page<OrderQueryVo>> list(
            @PathVariable @NotNull(message = "页码不可为空") @Max(value = 50, message = "页码不可超过50") Long page,
            @PathVariable @NotNull(message = "每页长度不可为空") @Range(min = 1, max = 50, message = "每页长度必须在1 到 50 之间") Long limit,
            OrderPageDto conditions,
            @ApiIgnore HttpServletRequest request) {
        conditions.setUserId(AuthContextHolder.getUserId(request));
        Page<OrderQueryVo> pageModel = new Page<>(page, limit);

        return Result.ok(this.orderInfoService.selectPage(pageModel, conditions));
    }

    @ApiOperation(value = "获取订单状态")
    @GetMapping("/auth/getStatusList")
    public Result<List<Map<String, Object>>> getStatusList() {
        return Result.ok(OrderStatusEnum.getStatusList());
    }

    @ApiOperation("取消订单")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderId", value = "订单的 id", required = true, paramType = "path", dataTypeClass = Long.class),
    })
    @GetMapping("/auth/cancelOrder/{orderId}")
    public Result cancelOrder(
            @PathVariable @Min(value = 0L, message = "订单 id 非法") Long orderId,
            @ApiIgnore HttpServletRequest request) {
        Long userId = AuthContextHolder.getUserId(request);
        RefundInfo refundInfo = this.orderInfoService.beginCancel(userId, orderId, PaymentTypeEnum.WEIXIN.getStatus());//仅添加了一条退款记录
        this.orderInfoService.finishCancel(orderId, refundInfo);//正是向院方、微信发起请求，调用系统模块更新浩源
        //如果取消订单完成失败，可以用定时任务定期检测进行中的退款记录
        return Result.ok(refundInfo);
    }

    @ApiOperation(value = "获取订单统计数据")
    @PostMapping("/inner/getCountMap")
    public OrderDaysVo getCountMap(@RequestBody OrderDayDto conditions) {
        return this.orderInfoService.countEveryDayOrder(conditions);
    }

}
